<template>
    <div class="loading" v-show="isLoding"></div>
    <div ref="sceneRef" id="scene" style="width: 100%; height: 100%;"></div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader';

const sceneRef = ref(null);
const isLoding = ref(true); // 加载状态

onMounted(() => {
    if (sceneRef.value) {
        const base3d = new Base3d(sceneRef.value);
    } else {
        console.error('Container is not ready');
    }
});

class Base3d {
    constructor(container) {
        this.container = container;
        this.camera;
        this.scene;
        this.renderer;
        this.controls;
        this.model;
        this.init();
        this.animate();
        this.onWindowResize(); // 初始化时调整尺寸
        window.addEventListener('resize', this.onWindowResize.bind(this)); // 监听窗口大小变化
    }

    init() {
        this.initScene();
        this.initCamera();
        this.initRender();
        this.initControls();
        this.addLights();
        this.addMesh();
    }

    initScene() {
        this.scene = new THREE.Scene();
    }

    initCamera() {
        this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        this.camera.position.set(0, 0, 5);
    }

    initRender() {
        this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
        this.renderer.setPixelRatio(window.devicePixelRatio);
        this.renderer.setSize(window.innerWidth, window.innerHeight);
        this.renderer.toneMapping = THREE.ACESFilmicToneMapping;
        this.renderer.toneMappingExposure = 1;
        this.renderer.setClearColor(0x000000, 0);
        if (this.container) {
            this.container.appendChild(this.renderer.domElement);
        } else {
            console.error('Container is not defined');
        }
    }

    render() {
        this.renderer.render(this.scene, this.camera);
    }

    animate() {
        this.renderer.setAnimationLoop(this.render.bind(this));
    }

    initControls() {
        this.controls = new OrbitControls(this.camera, this.renderer.domElement);
        this.controls.enableDamping = true;
        this.controls.dampingFactor = 0.05;
        this.controls.enableZoom = false; // 禁用鼠标滚轮缩放
        this.controls.maxPolarAngle = Math.PI / 2; // 限制只能左右旋转
        this.controls.minPolarAngle = Math.PI / 2;
    }

    addLights() {
        const ambientLight = new THREE.AmbientLight(0xffffff, 2);
        this.scene.add(ambientLight);

        const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
        directionalLight.position.set(5, 5, 5);
        directionalLight.castShadow = true;
        this.scene.add(directionalLight);
    }

    setModel(modelName) {
        return new Promise((resolve, reject) => {
            const dracoLoader = new DRACOLoader();
            dracoLoader.setDecoderPath('https://www.gstatic.com/draco/versioned/decoders/1.5.6/'); // 使用 CDN 提供的解码器路径
            dracoLoader.setDecoderConfig({ type: 'js' });
            dracoLoader.preload();

            const loader = new GLTFLoader().setPath('/gltf/'); // 设置模型路径
            loader.setDRACOLoader(dracoLoader); // 将 DRACOLoader 实例设置到 GLTFLoader

            loader.load(modelName, (gltf) => {
                console.log(gltf);
                this.model = gltf.scene;
                this.model.scale.set(1.5, 2, 1.5);
                this.model.position.set(-0.5, -2, 0);

                // 初始化时向右旋转 80 度
                this.model.rotation.y = -THREE.MathUtils.degToRad(90); // 顺时针旋转 80 度

                this.scene.add(this.model);

                resolve(`${modelName} 模型添加成功`);

            }, undefined, (error) => {
                console.error('模型加载失败：', error);
                reject(error);
            });

        });


    }

    addMesh() {
        this.setModel('企业楼3.glb') // 确保路径正确
            .then((message) => {
                console.log(message);
                console.log("111")
                isLoding.value = false; // 加载完成后设置为 false
            })
            .catch((error) => {
                console.error('模型加载失败：', error);
            });

    }

    onWindowResize() {
        const width = this.container.clientWidth;
        const height = this.container.clientHeight;
        this.camera.aspect = width / height;
        this.camera.updateProjectionMatrix();
        this.renderer.setSize(width, height);
    }
}

// onUnmounted(() => {
//   window.removeEventListener('resize', this.onWindowResize.bind(this)); // 移除监听
// });
</script>

<style lang="scss" scoped>
.loading {
  position: relative;
  width: 30px;
  height: 30px;
  border: 2px solid #000;
  border-top-color: rgba(0, 0, 0, 0.2);
  border-right-color: rgba(0, 0, 0, 0.2);
  border-bottom-color: rgba(0, 0, 0, 0.2);
  border-radius: 100%;
  animation: circle infinite 0.75s linear;
  margin: auto;
}

@keyframes circle {
  0% {
    transform: rotate(0);
  }
  100% {
    transform: rotate(360deg);
  }
}
</style>